﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Threading;
using System.IO;
using System.Windows;
using BrainTechLLC;
using BrainTechLLC.WPF;

namespace ImageAppDataModels
{
    public class DirectoryWatcher : BaseNotifyPropertyChanged, INotifyPropertyChanged
    {
        protected string _directory;
        protected FileSystemWatcher _watcher;
        protected List<IWatcherNotifiable> _notify = new List<IWatcherNotifiable>();
        protected bool _started;

        public string Directory
        {
            get { return _directory; }
            set
            {
                if (_directory != value)
                {
                    _directory = value;
                    OnPropertyChanged("Directory");
                }
            }
        }

        public DirectoryWatcher(string s, string filter)
        {
            _watcher = new FileSystemWatcher(s, filter);
            _watcher.Changed += new FileSystemEventHandler(_watcher_Changed);
            _watcher.Created += new FileSystemEventHandler(_watcher_Created);
            _watcher.Deleted += new FileSystemEventHandler(_watcher_Deleted);
        }

        public void Dispose()
        {
            if (_watcher != null)
            {
                _watcher.EnableRaisingEvents = false;
                _watcher.Dispose();
                _watcher = null;
            }
        }

        public void Attach(IWatcherNotifiable notify)
        {
            _notify.Add(notify);
            if (!_started)
            {
                _started = true;
                _watcher.EnableRaisingEvents = true;
            }
        }

        public void Detach(IWatcherNotifiable notify)
        {
            _notify.Remove(notify);

            if (_notify.Count == 0)
            {
                _started = false;
                if (_watcher != null)
                {
                    _watcher.EnableRaisingEvents = false;
                }
            }
        }

        void _watcher_Deleted(object sender, FileSystemEventArgs e)
        {
            var dispatcher = Application.Current.Dispatcher;
            if (dispatcher != null)
            {
                dispatcher.BeginInvoke(new OneParamDelegate((o) => _notify.ForEach((w) => w.RemoveByFileName(o.ToString()))), e.FullPath);
            }
            else
            {
                _notify.ForEach((w) => w.RemoveByFileName(e.FullPath));
            }
        }

        void _watcher_Created(object sender, FileSystemEventArgs e)
        {
            var dispatcher = Application.Current.Dispatcher;
            
            dispatcher.RunOnDispatcher(
                new OneParamDelegate((o) => _notify.ForEach((w) => w.AddByFileName(o.ToString()))), 
                DispatcherPriority.Background, 
                e.FullPath);
        }

        void _watcher_Changed(object sender, FileSystemEventArgs e)
        {
            //if (e.ChangeType == WatcherChangeTypes.Renamed)
            //{
            //    var dispatcher = Application.Current.Dispatcher;
            //    if (dispatcher != null)
            //    {
            //        //dispatcher.BeginInvoke(new OneParamDelegate((o) => _notify.ForEach((w) => w.FileNameChanged(o.ToString()))), e.FullPath);
            //    }
            //    else
            //    {
            //        //_notify.ForEach((w)=>w.FileNameChanged(e.FullPath));
            //    }
            //}
        }        
    }
}
